﻿namespace Ngs.Expressions
{
    using System;
    using System.Linq.Expressions;

    public static class ExpressionExtensions
    {
        static ExpressionExtensions()
        {
        }

        public static Expression Replace(Type type, LambdaExpression lambda)
        {
            // Throw if Null
            ExceptionFactory.ThrowIfArgumentNull(lambda);

            ParameterExpression parameter = lambda.Parameters[0];

            // Create replacement parameter
            ParameterExpression nativeParam = Expression.Parameter(type, parameter.Name);
            return ExpressionReplacer.ReplaceAll(lambda, new[] { parameter }, new[] { nativeParam });
        }

        public static string GetMemberName<T, TMember>(this Expression<Func<T, TMember>> memberExpression)
        {
            return ((MemberExpression)memberExpression.Body).Member.Name;
        }

        public static int PropertyValue<T>(this  T model, Expression<Func<T, int>> action)
        {
            return GetValue(model, action);
        }

        public static bool PropertyValue<T>(this T model, Expression<Func<T, bool>> action)
        {
            return GetValue(model, action);
        }

        public static string PropertyValue<T>(this T model, Expression<Func<T, string>> action)
        {
            return GetValue(model, action);
        }

        public static V GetValue<T, V>(this T model, Expression<Func<T, V>> action)
        {
            var function = action.Compile();
            return function(model);
        }
    }
}
